package com.example.springboot.aop.service;

import com.example.springboot.aop.dao.SystemLogMapper;
import com.example.springboot.aop.entity.SystemLogModel;
import com.example.springboot.aop.utils.DateUtils;
import com.example.springboot.aop.utils.GsonUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * 获取日志信息，保存数据库
 */
@Service
public class SystemLogService {

    private static final Logger logger = LoggerFactory.getLogger(SystemLogService.class);
    @Autowired
    private SystemLogMapper systemLogMapper;

    /**
     * 全文搜各类型结果条数查询
     *
     * @param ModuleID   :菜单id
     * @param LogAction  :操作方式（保存、修改，删除、查询等）
     * @param LogContent :操作内容（例如：ResourceType:数据类型;TerminalMac:终端mac）
     * @param:注解使用方法： logService(1, "查询",
     * "Content:关键字；ResourceType:真实身份；Phone:手机号", request)，
     * 注意LogContent中的字段要和定义的实体保持一致，负责封装不到实体中。
     */
    public void logService(int ModuleID, String LogAction, String LogContent, HttpServletRequest request) {
        String logIP = request.getHeader("X-Real-IP");
        if (StringUtils.isEmpty(logIP)) {
            logIP = request.getRemoteAddr();
        }
        try {

            SystemLogModel slm = getControllerMethodDescription(ModuleID, LogAction, LogContent, request);
            slm.setLogIP(logIP);
            slm.setTimeFlag(DateUtils.currentDatetime());
            String UserID = request.getParameter("UserID");
            String UserName = request.getParameter("UserName");
            if (null == UserID || null == UserName) {
                logger.debug("操作日志-->日志添加:用户名或用户ID为空，返回不添加日志!");
            } else {
                slm.setFlagID(Integer.parseInt(UserID));
            }
            slm.setFlagName(UserName);

            // *========控制台输出=========*//
            logger.debug("=====注解参数获取开始=====");
            logger.debug("操作日志-->日志添加:" + slm.toString());
            // *========数据库日志=========*//

            this.saveLog(slm);
        } catch (Exception e) {
            // 记录本地异常日志
            logger.error("==前置通知异常==");
            logger.error("异常信息:{}", e.getMessage());
        }
    }

    /**
     * 保存日志记录
     */
    public void saveLog(SystemLogModel slm) {
        try {
            systemLogMapper.saveOrUpdate(slm);
        } catch (Exception e) {
            // 记录本地异常日志
            logger.error("==前置通知异常==");
            logger.error("异常信息:{}", e.getMessage());
        }
    }

    /**
     * 封装实体类
     */
    public SystemLogModel getSystemLogModel(int ModuleID, String LogAction, HttpServletRequest request) {
        SystemLogModel slm = new SystemLogModel();
        String logIP = request.getHeader("X-Real-IP");
        if (StringUtils.isEmpty(logIP)) {
            logIP = request.getRemoteAddr();
        }
        try {
            slm = getControllerMethodDescription(ModuleID, LogAction, null, request);
            slm.setLogIP(logIP);
            slm.setTimeFlag(DateUtils.currentDatetime());
            String UserID = request.getParameter("UserID");
            String UserName = request.getParameter("UserName");
            if (null == UserID || null == UserName) {
                logger.debug("操作日志-->日志添加:用户名或用户ID为空，返回不添加日志!");
            } else {
                slm.setFlagID(Integer.parseInt(UserID));
            }
            slm.setFlagName(UserName);

            // *========控制台输出=========*//
            logger.debug("=====注解参数获取开始=====");
            logger.debug("操作日志-->日志添加:" + slm.toString());
            // *========数据库日志=========*//

        } catch (Exception e) {
            // 记录本地异常日志
            logger.error("==前置通知异常==");
            logger.error("异常信息:{}",e.getMessage());
        }

        return slm;
    }

    /**
     * 拼接变量为实体对象
     *
     * @param @param  ModuleID 模块ID
     * @param @param  LogAction 模块名称
     * @param @param  LogContent 模块内容
     * @param @return 模块对象
     * @param @throws Exception
     * @return SystemLogModel
     * @Description: TODO
     * @author cjy
     * @date 2016-11-14
     */
    private SystemLogModel getControllerMethodDescription(int ModuleID, String LogAction, String LogContent, HttpServletRequest request)
            throws Exception {

        SystemLogModel model = new SystemLogModel();
        model.setModuleID(ModuleID);
        model.setLogAction(LogAction);

        // 获取请求参数(ResourceType:1,TerminalMac:DF-FG-JK-09-TU)
        Map<String, String> fieldMap = getRequestParamInfo(request);
        // 注解值(ResourceType:数据类型；TerminalMac:终端mac)
        Map<String, String> propMap = getPropertyAndValues(LogContent);

        StringBuilder sub = new StringBuilder();
        String result = "";
        for (String key : propMap.keySet()) {
            String content = propMap.get(key);
            if (StringUtils.isEmpty(content)) {
                continue;
            }
            if ("LogContent".equals(key)) {
                result = " [" + content + "] ";
            } else {
                // 字段值
                String filedValue = fieldMap.get(key);
                filedValue = StringUtils.isEmpty(filedValue) ? "" : filedValue;
                if (StringUtils.isNotBlank(content)) {
                    sub.append(" [" + content + "] " + filedValue);
                }
            }
        }
        model.setLogContent(result + sub.toString());
        model.setCondition(GsonUtils.parseBeanToFormatJson(fieldMap));
        return model;
    }

    /**
     * 获取注解日志记录属性及值
     *
     * @param LogContent
     */
    private Map<String, String> getPropertyAndValues(String LogContent) {

        Map<String, String> map = new HashMap<String, String>();
        if (StringUtils.isNotBlank(LogContent)) {
            if (LogContent.contains(";")) {
                String[] contents = LogContent.split(";");
                if (contents == null || contents.length <= 0) {
                    return map;
                }
                for (String str : contents) {
                    String[] split = str.split(":");
                    if (split != null && split.length == 2) {
                        map.put(split[0], split[1]);
                    }
                }
            } else {
                map.put("LogContent", LogContent);
            }
        }
        return map;
    }

    /**
     * 获取request请求参数
     *
     * @param request
     * @return
     */
    @SuppressWarnings("unchecked")
    private Map<String, String> getRequestParamInfo(HttpServletRequest request) {

        Map<String, String> map = new HashMap<String, String>();
        Map<String, String[]> paraMap = request.getParameterMap();
        for (String key : paraMap.keySet()) {
            String[] values = paraMap.get(key);
            Map<String, String> result = this.getTransferResult(key, values);
            map.putAll(result);
        }
        return map;
    }

    /**
     * 将数组转为字符串
     *
     * @param values
     * @return
     */
    private Map<String, String> getTransferResult(String key, String[] values) {

        Map<String, String> map = new HashMap<String, String>();
        String result = "";
        if (values != null && values.length > 0) {
            for (String str : values) {
                if (GsonUtils.isJson(str,Map.class)) {
                    Map<String, String> jsonMap = GsonUtils.fromJson(str, Map.class);
                    map.putAll(jsonMap);
                } else {
                    result += str + ",";
                }
            }
            if (StringUtils.isNotBlank(result)) {
                result = result.substring(0, result.lastIndexOf(","));
                map.put(key, result);
            }
        }
        return map;
    }
}